package cn.lili.modules.grab.aop.request;

import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.StringUtils;
import cn.lili.exchange.AmqpExchangeProperties;
import cn.lili.modules.grab.dingdong.config.DingdongConfig;
import cn.lili.modules.grab.dingdong.reps.order.CreateOrderRespose;
import cn.lili.modules.grab.dingdong.res.order.CreateOrderRequest;
import cn.lili.modules.system.constants.RequestLogTypeConstant;
import cn.lili.modules.system.entity.dos.RequestLog;
import cn.lili.routing.ThirdCallLogKey;
import cn.lili.util.AmqpMessage;
import cn.lili.util.AmqpSender;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 第三方请求日志注解注解
 *
 * @author Chopper
 */
@Aspect
@Slf4j
@Component
public class RequestLogAnntionAop {

    @Resource
    private DingdongConfig dingdongConfig;
    @Resource
    private AmqpSender amqpSender;
    @Resource
    private AmqpExchangeProperties amqpExchangeProperties;

    @Around("@annotation(cn.lili.modules.grab.aop.request.RequestLogAnntion)")
    public Object interceptor(ProceedingJoinPoint joinPoint) {
        RequestLog requestLog = new RequestLog();
        try {
            //获取请求参数
            Object[] args = joinPoint.getArgs();
            requestLog.setQueryString(JSONObject.toJSONString(args[0]));

            //获取注解参数
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            RequestLogAnntion requestLogAnntion = method.getAnnotation(RequestLogAnntion.class);
            String type = requestLogAnntion.type();
            String typeName = requestLogAnntion.typeName();
            requestLog.setType(type);
            requestLog.setTypeName(typeName);

            //获取相应参数
            Object result = joinPoint.proceed();
            requestLog.setResponse(JSONObject.toJSONString(result));
            return result;
        } catch (Throwable e) {
            if(e instanceof ServiceException){
                ServiceException serviceException = (ServiceException) e;
                requestLog.setResponse(serviceException.getMsg());
                throw  serviceException;
            }else{
                throw new RuntimeException();
            }

        } finally {
            //构建taskId
            builderRequest(requestLog);
            //构建日志
            builderRespose(requestLog);
            //发送日志请求
            amqpSender.send(
                    AmqpMessage.builder()
                            .exchange(amqpExchangeProperties.getMsg())
                            .routingKey(ThirdCallLogKey.REQUEST_LOG)
                            .message(requestLog)
                            .build());
        }
    }

    /**
     * 构建taskId
     */
    public void builderRequest(RequestLog requestLog) {
        if (RequestLogTypeConstant.QI_DING_DONG_CREATE_ORDER.equals(requestLog.getType())) {
            CreateOrderRequest createOrderRequest = JSONObject.parseObject(requestLog.getQueryString(), CreateOrderRequest.class);
            if(Objects.isNull(requestLog.getItemTaskId())){
                requestLog.setItemTaskId(createOrderRequest.getTrade_no());
            }
        }
    }

    /**
     * 构建日志
     */
    public void builderRespose(RequestLog requestLog) {
        //如果为企叮咚创建订单请求
        if (RequestLogTypeConstant.QI_DING_DONG_CREATE_ORDER.equals(requestLog.getType())) {
            try {
                CreateOrderRespose createOrderRespose = JSONObject.parseObject(requestLog.getResponse(), CreateOrderRespose.class);
                requestLog.setStatusCode(createOrderRespose.getBaseResult().getStatus());
                requestLog.setUrl(dingdongConfig.getCreateOrderUrl());
            }catch (Exception e){
                requestLog.setStatusCode("500");
                log.error(e.getMessage());
            }

        }
    }
}